﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Extensions;

namespace PlantPick
{
    class Detection
    {
		private Mat GC, Bi_GC = new Mat(), erodeimg = new Mat(), cannydstx = new Mat(), diatedst = new Mat();
		private Mat[] channels;


		private int minArea = 150;
		private int maxArea = 20000;
		public Mat ImagePreProc(Mat SrcImg)
		{

			Cv2.Split(SrcImg, out channels);
			GC = channels[1];
			Cv2.Threshold(GC, Bi_GC, 130, 255, ThresholdTypes.Binary);
			Mat kernel = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(5, 5), new Point(-1, -1));
			Cv2.Erode(Bi_GC, erodeimg, kernel);
			Cv2.Erode(erodeimg, erodeimg, kernel);
			Cv2.Dilate(erodeimg, diatedst, kernel);
			Cv2.Dilate(diatedst, diatedst, kernel);
			return diatedst;
		}

		public LineSegmentPoint ImageRootDect(Mat ProcDst, Mat framemat)
		{
			Cv2.Canny(ProcDst, cannydstx, 150, 200, 3, false);
			LineSegmentPoint[] plines = Cv2.HoughLinesP(cannydstx, 1, Cv2.PI / 180.0, 50, 50, 10);
			//findContours(cannydstx, contours, hierarchy, CV_RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(-1, -1));

			if (plines.Length > 0)
			{
				//for (int i = 0; i < plines.Length && i <= 0; i++)//plines.size()
				for (int i = 0; i < plines.Length; i++)//plines.size()
				{
					LineSegmentPoint hline = plines[i];
					//line(ROI, Point(hline[0], hline[1]), Point(hline[2], hline[3]), color, 1.5, LINE_AA);
					int x = (hline.P1.X + hline.P2.X) / 2;
					int y = (hline.P1.Y + hline.P2.Y) / 2;
					Cv2.Rectangle(framemat, new Point(x - 13, y - 13), new Point(x + 13, y + 13), new Scalar(0, 0, 255), 3, LineTypes.Link8, 0);
					//putText(ROI, "Hello ", Point(50, 60), FONT_HERSHEY_SIMPLEX, 2, Scalar(0, 0, 255), 4, 8);
				}
			}
			return plines.Length > 0 ? plines[0] : new LineSegmentPoint();
		}


		public Mat ImageLeafDect(Mat ProcDst, Mat framemat)
		{

			HierarchyIndex[] hierarchy;
			Mat kernel1 = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(5, 5), new Point(-1, -1));
			Mat kernel2 = Cv2.GetStructuringElement(MorphShapes.Rect, new Size(3, 3), new Point(-1, -1));
			Mat Dilaimg = new Mat(), cannydst2 = new Mat();
			Cv2.Erode(ProcDst, erodeimg, kernel1);
			Cv2.Dilate(erodeimg, Dilaimg, kernel2);
			//dilate(Dilaimg, Dilaimg, kernel2);
			//morphologyEx(ProcDst, Dilaimg, CV_MOP_OPEN, kernel);
			Cv2.Canny(Dilaimg, cannydst2, 150, 200, 3, true);
			Point[][] contours;
			Cv2.FindContours(cannydst2,out contours,out hierarchy, RetrievalModes.External, ContourApproximationModes.ApproxSimple, new Point(-1, -1));

			List<Point[]> contoursList = new List<Point[]>();
			foreach(Point[] itc in contours){
				if (itc.Length < minArea || itc.Length > maxArea)
				{
					continue;
				}
				else {
					contoursList.Add(itc);
				}
			}
			foreach (Point[] contour in contoursList) {
				double area = Cv2.ContourArea(contour);
				Rect maxRect = Cv2.BoundingRect(contour);
				if ((area / (maxRect.Width * maxRect.Height)) > 0.3)
				{
					Cv2.Rectangle(framemat, maxRect.TopLeft, maxRect.BottomRight, new Scalar(0, 0, 255), 3, LineTypes.Link8);
				}
			}
			return framemat;
		}
	}
}